package net.wicp.tams.common.metrics.annotation;

import java.lang.annotation.Annotation;
import java.lang.reflect.Field;

import com.codahale.metrics.Counter;
import com.codahale.metrics.Gauge;
import com.codahale.metrics.Metric;

import lombok.extern.slf4j.Slf4j;
import net.wicp.tams.common.metrics.core.TsMetricAbstractGroup;
import net.wicp.tams.common.spring.autoconfig.beans.FieldBean;

@Slf4j
public class MetricsAnnotationDo extends FieldBean<Object> {

	public MetricsAnnotationDo(Annotation annotationInst, Field field) {
		super(annotationInst, field);
	}

	@SuppressWarnings("rawtypes")
	private Class getClass(Class classz, boolean isThisClass) {
		if (classz.getName().equals("java.lang.Object")) {
			if (isThisClass) {
				return field.getDeclaringClass();
			} else {
				return TsMetricAbstractGroup.class;
			}
		} else {
			return classz;
		}
	}

	@Override
	public Object doWithAnnotation() {
		TsMetricAbstractGroup tsgroup = applicationContext.getBean(TsMetricAbstractGroup.class);
		Metric metric = null;
		if (annotationInst instanceof CounterTams) {
			CounterTams counterTams = (CounterTams) annotationInst;
			metric = tsgroup.newCounter(getClass(counterTams.classz(), counterTams.isThisClass()), counterTams.value());
		} else if (annotationInst instanceof MeterTams) {
			MeterTams meterTams = (MeterTams) annotationInst;
			metric = tsgroup.newMeter(getClass(meterTams.classz(), meterTams.isThisClass()), meterTams.value());
		} else if (annotationInst instanceof HistogramTams) {
			HistogramTams histogramTams = (HistogramTams) annotationInst;
			metric = tsgroup.newHistogram(getClass(histogramTams.classz(), histogramTams.isThisClass()),
					histogramTams.value());
		} else if (annotationInst instanceof TimerTams) {
			TimerTams timerTams = (TimerTams) annotationInst;
			metric = tsgroup.newTimer(getClass(timerTams.classz(), timerTams.isThisClass()), timerTams.value());
		} else if (annotationInst instanceof GaugeTams) {
			GaugeTams gaugeTams = (GaugeTams) annotationInst;
			final Counter newCounter = tsgroup.newCounter(getClass(gaugeTams.classz(), gaugeTams.isThisClass()),
					gaugeTams.counterValue());
			metric = tsgroup.newGauge(new Gauge<Integer>() {
				@Override
				public Integer getValue() {
					return (int) newCounter.getCount();
				}
			}, getClass(gaugeTams.classz(), gaugeTams.isThisClass()), gaugeTams.value());
		}
		log.info("the field:{} has inited", field.getName());
		return metric;
	}

}
